package org.amos.server.modules.upms.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import org.amos.core.basic.utils.AmosUtils;
import org.amos.satoken.api.UserAuthApi;
import org.amos.satoken.domain.bo.AuthInfo;
import org.amos.server.modules.upms.entity.Role;
import org.amos.server.modules.upms.entity.User;
import org.amos.server.modules.upms.service.IRoleService;
import org.amos.server.modules.upms.service.IUserRoleService;
import org.amos.server.modules.upms.service.IUserService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @desc: 用户认证
 * @author: liubt
 * @date: 2022-08-18 15:38
 **/
@Service
@RequiredArgsConstructor
public class UserAuthApiServiceImpl implements UserAuthApi {
    private final IUserService userService;
    private final IUserRoleService userRoleService;
    private final IRoleService roleService;

    @Override
    public AuthInfo getUserByAccount(String account) {
        User user = userService.getUserByAccount(account);
        return this.assembleAuthInfo(user);
    }

    @Override
    public AuthInfo getUserByMobile(String mobile) {
        User user = userService.getUserByMobile(mobile);
        return this.assembleAuthInfo(user);
    }

    @Override
    public AuthInfo authBySocialIdAndSourceType(String socialId, Integer sourceType) {
        return null;
    }

    @Override
    public List<String> getUserRoles(Object loginId, String loginType) {
        if (StpUtil.getLoginType().equals(loginType)) {
            Set<Long> roles = userRoleService.findRoleIdsByUserId(Long.parseLong(String.valueOf(loginId)));
            return roles.stream().map(String::valueOf).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    @Override
    public List<String> getUserPermissions(Object loginId, String loginType) {
        if (StpUtil.getLoginType().equals(loginType)) {
            User user = userService.findById(Long.parseLong((String) loginId));
            return roleService.getUserPermissions(user).stream().collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    private AuthInfo assembleAuthInfo(User user) {
        AuthInfo authInfo = null;
        if (Objects.nonNull(user)) {
            authInfo = AmosUtils.copy(user, AuthInfo.class);
            // 设置角色权限信息
            Set<Role> roles = userRoleService.findRolesByUserId(authInfo.getId());
            Set<String> roleAlias = roles.stream().map(Role::getAlias).collect(Collectors.toSet());
            String roleName = roles.stream().map(Role::getName).collect(Collectors.joining(StrUtil.COMMA));
            List<String> permissions = this.getUserPermissions(authInfo.getId().toString(), StpUtil.TYPE);
            authInfo.setRoleAlis(roleAlias);
            authInfo.setRoleName(roleName);
            authInfo.setPermissions(CollUtil.newHashSet(permissions));
        }

        return authInfo;
    }
}
